package com.wno704.system.util;

import groovy.lang.Binding;
import groovy.lang.GroovyClassLoader;
import groovy.lang.Script;
import org.codehaus.groovy.runtime.InvokerHelper;

/**
 * @ClassName GroovyUtil
 * @Description TODO
 * @Author wno704
 * @Date 2022/6/7 18:14
 * @Version 1.0
 */
public class GroovyUtil {

    /**
     * 将groovy脚本编译成class
     *
     * @param groovyScript
     * @return
     */
    public static Class<?> parseClass(String groovyScript) {
        ClassLoader parent = GroovyUtil.class.getClassLoader();

        @SuppressWarnings("resource")
        GroovyClassLoader loader = new GroovyClassLoader(parent);
        @SuppressWarnings("rawtypes")
        Class groovyClass = loader.parseClass(groovyScript);
        return groovyClass;
    }

    /**
     * 执行groovy脚本
     * 脚本中须要有名为groovyParam的变量接收入参
     *
     * @param groovyClass 脚本编译的class，一般放在缓存中
     * @param param       入参，为保持代码的通用，只能传一个参数
     * @return
     */
    public static Object executeGroovy(Class<?> groovyClass, Object param) {
        Binding binding = new Binding();
        binding.setVariable("$groovyParam", param);
        Script script = InvokerHelper.createScript(groovyClass, binding);
        Object result = script.run();
        return result;
    }

    /**
     * @Description: 执行groovy脚本 - 方法重载一个 , 脚本中须要有名为groovyParam的变量接收入参
     * @Param: [groovyClass, param, otherParam]   groovyClass 脚本编译的class，一般放在缓存中  param 入参  otherParam 其他入参，目前功能是为了：接口返回入库
     * @return: java.lang.Object
     * @Author: wno704
     * @Date: 2022/6/7
     */
    public static Object executeGroovy(Class<?> groovyClass, Object param, Object otherParam) {
        Binding binding = new Binding();
        binding.setVariable("$groovyParam", param);
        binding.setVariable("$otherGroovyParam", otherParam);
        Script script = InvokerHelper.createScript(groovyClass, binding);
        Object result = script.run();
        return result;
    }

    /**
     * @Description: 执行groovy脚本 -变量接收入参自定义，和接收值对应
     * @Param: [groovyClass, paramNames, params]   groovyClass 脚本编译的class，一般放在缓存中  paramNames[] 脚本绑定参数名  params[] 入参数据，和paramNames对应：接口返回入库
     * @return: java.lang.Object
     * @Author: wno704
     * @Date: 2022/6/7
     */
    public static Object executeGroovys(Class<?> groovyClass, String[] paramNames, Object[] params) {
        Binding binding = new Binding();
        for (int i = 0; i < paramNames.length; i++) {
            binding.setVariable(paramNames[i], params[i]);
        }
        Script script = InvokerHelper.createScript(groovyClass, binding);
        Object result = script.run();
        return result;
    }

}
